package com.smedi.ismedi.authoritymanagement.core.port.adapter.restful;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.smedi.ismedi.authority.starter.annotation.SkipAuthority;
import com.smedi.ismedi.authoritymanagement.api.dto.request.*;
import com.smedi.ismedi.authoritymanagement.api.dto.response.*;
import com.smedi.ismedi.authoritymanagement.api.feign.RemoteAuthorityRoleManagementFeignApi;
import com.smedi.ismedi.authoritymanagement.core.application.command.RoleAssignmentListQueryCommand;
import com.smedi.ismedi.authoritymanagement.core.application.command.RoleBasicCommand;
import com.smedi.ismedi.authoritymanagement.core.application.command.RoleListQueryCommand;
import com.smedi.ismedi.authoritymanagement.core.application.command.RolePermissionDetailCommand;
import com.smedi.ismedi.authoritymanagement.core.application.query.RoleBasicQueryService;
import com.smedi.ismedi.authoritymanagement.core.application.service.RoleBasicApplicationService;
import com.smedi.ismedi.authoritymanagement.core.application.service.RolePermissionDetailApplicationService;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.Role;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RoleAssignment;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.web.starter.common.PaginationData;
import com.smedi.ismedi.web.starter.common.ResponseData;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: xulinjun
 * @Date: 2021-7-2 20:17
 */
@Slf4j
@RestController
@AllArgsConstructor
public class AuthorityRoleManagementController implements RemoteAuthorityRoleManagementFeignApi {
    private final DozerUtil dozerUtil;
    private final AdapterConverter adapterConverter;
    private final RoleBasicQueryService roleBasicQueryService;
    private final RoleBasicApplicationService roleBasicApplicationService;
    private final RolePermissionDetailApplicationService rolePermissionDetailApplicationService;

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<RoleBasicResponse> postSaveRoleBasic(RoleBasicRequest roleBasicRequest) {
        RoleBasicCommand roleBasicCommand = dozerUtil.convertor(roleBasicRequest, RoleBasicCommand.class);
        return new ResponseData<RoleBasicResponse>().success(dozerUtil.convertor(roleBasicApplicationService.saveRoleBasic(roleBasicCommand), RoleBasicResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<RoleBasicResponse>> postBatchSaveRoleBasic(List<RoleBasicRequest> roleBasicRequest) {
        List<RoleBasicCommand> roleBasicCommands = dozerUtil.convertor(roleBasicRequest, RoleBasicCommand.class);
        return new ResponseData<List<RoleBasicResponse>>().success(dozerUtil.convertor(roleBasicApplicationService.batchSaveRoleBasic(roleBasicCommands), RoleBasicResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> deleteRoleBasic(Long roleId) {
        roleBasicApplicationService.deleteRoleBasic(roleId);
        return new ResponseData<Boolean>().success(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> deleteBatchDeleteRoleBasics(List<Long> roleIds) {
        roleBasicApplicationService.batchDeleteRoleBasics(roleIds);
        return new ResponseData<Boolean>().success(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<PaginationData<RoleBasicResponse>> getQueryRoleBasicPagination(Long offset, Long pageSize, String roleName,String roleType) {
        IPage pagination = roleBasicQueryService.getRoleBasicPaginationByRoleName(offset, pageSize, roleName,roleType);
        PaginationData PaginationData = dozerUtil.convertor(pagination, PaginationData.class);
        return new ResponseData<PaginationData<RoleBasicResponse>>().success(PaginationData);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<RoleBasicResponse>> getQueryRolesByPersonId(Long personId) {
        return new ResponseData<List<RoleBasicResponse>>().success(dozerUtil.convertor(roleBasicQueryService.getRolesByPersonId(personId), RoleBasicResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> postBatchSaveOneRoleForMultiPerson(OneRoleMultiPersonRequest oneRoleMultiPersonRequest) {
        roleBasicApplicationService.batchSaveOneRoleForMultiPerson(oneRoleMultiPersonRequest.getRoleId(), oneRoleMultiPersonRequest.getPersonIds());
        return new ResponseData<Boolean>().success(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> postBatchSaveMultiRoleForOnePerson(MultiRoleOnePersonRequest multiRoleOnePersonRequest) {
        roleBasicApplicationService.batchSaveMultiRoleForOnePerson(multiRoleOnePersonRequest.getRoleIds(), multiRoleOnePersonRequest.getPersonId());
        return new ResponseData<Boolean>().success(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> deleteRoleMember(Long roleMemberId) {
        roleBasicApplicationService.deleteRoleMemberByRoleMemberId(roleMemberId);
        return new ResponseData<Boolean>().success(true);
    }

    // todo 等下继续改

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<PaginationData<RoleMemberResponse>> getQueryRoleMemberPagination(Long offset, Long pageSize, Long roleId, String lastName, String userName, String mobile) {
        IPage pagination = roleBasicQueryService.getRoleMemberPaginationByLastNameAndUserNameAndMobile(offset, pageSize, roleId, lastName, userName, mobile);
        PaginationData PaginationData = dozerUtil.convertor(pagination, PaginationData.class);
        return new ResponseData<PaginationData<RoleMemberResponse>>().success(PaginationData);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<PersonRoleRelationshipResponse>> getQueryPersonRoleRelationshipByPersonIds(List<Long> personIds, Long roleId) {
        List<Long> hasRole = roleBasicQueryService.getPersonIdsByRoleId(roleId);
        List<PersonRoleRelationshipResponse> list = personIds.stream().map(personId ->
                new PersonRoleRelationshipResponse()
                        .setPersonId(personId)
                        .setHasRole(hasRole.contains(personId))
        ).collect(Collectors.toList());

        return new ResponseData<List<PersonRoleRelationshipResponse>>().success(list);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<Long>> getQueryAllPersonIdsByRoleId(Long roleId) {
        return new ResponseData<List<Long>>().success(roleBasicQueryService.getPersonIdsByRoleId(roleId));
    }

    @Override
    @SkipAuthority
    public ResponseData<List<Long>> getQueryAllPersonIdsByRoleIds(List<Long> roleIds) {
        return new ResponseData<List<Long>>().success(roleBasicQueryService.getPersonIdsByRoleId(roleIds));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> postBatchSaveRolePermissionDetails(RolePermissionDetailGroupRequest rolePermissionDetailGroupRequest) {
        List<RolePermissionDetailCommand> rolePermissionDetailCommands = dozerUtil.convertor(rolePermissionDetailGroupRequest.getRolePermissionDetails(), RolePermissionDetailCommand.class);
        String rootCode = rolePermissionDetailGroupRequest.getRootCode();
        Long roleId = rolePermissionDetailGroupRequest.getRoleId();
        rolePermissionDetailApplicationService.batchSaveRolePermissionDetail(rootCode, roleId, rolePermissionDetailCommands);

        return new ResponseData<Boolean>().success(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<RoleBasicResponse>> getQueryAllPersonIdsByRoleId(String roleName, boolean fuzzy, boolean showPersonId) {
        return new ResponseData<List<RoleBasicResponse>>().success(dozerUtil.convertor(roleBasicQueryService.getRolesByRoleName(roleName, fuzzy, showPersonId), RoleBasicResponse.class));
    }

    @Override
    public ResponseData<List<RoleResponse>> getRoleList(RoleListQueryRequest roleListQueryRequest) {
        RoleListQueryCommand roleListQueryCommand = adapterConverter.roleListQueryRequestToRoleListQueryCommand(roleListQueryRequest);
        List<Role> roles = roleBasicQueryService.getRoleList(roleListQueryCommand);
        List<RoleResponse> roleResponses = adapterConverter.roleToRoleResponse(roles);
        return new ResponseData<>().success(roleResponses);
    }

    @Override
    public ResponseData<List<RoleResponse>> getRoleListWithoutToken(RoleListQueryRequest roleListQueryRequest) {
        RoleListQueryCommand roleListQueryCommand = adapterConverter.roleListQueryRequestToRoleListQueryCommand(roleListQueryRequest);
        List<Role> roles = roleBasicQueryService.getRoleListWithoutToken(roleListQueryCommand);
        List<RoleResponse> roleResponses = adapterConverter.roleToRoleResponse(roles);
        return new ResponseData<>().success(roleResponses);
    }

    @Override
    public ResponseData<List<RoleAssignmentResponse>> getRoleAssignmentList(RoleAssignmentListQueryRequest roleAssignmentListQueryRequest) {
        RoleAssignmentListQueryCommand roleAssignmentListQueryCommand = adapterConverter.roleAssignmentListQueryRequestToRoleAssignmentListQueryCommand(roleAssignmentListQueryRequest);
        List<RoleAssignment> roleAssignments = roleBasicQueryService.getRoleAssignmentList(roleAssignmentListQueryCommand);
        List<RoleAssignmentResponse> roleAssignmentResponses = adapterConverter.roleAssignmentToRoleAssignmentResponse(roleAssignments);
        return new ResponseData<>().success(roleAssignmentResponses);
    }

    @Override
    public ResponseData<List<RoleAssignmentResponse>> getRoleAssignmentListWithoutToken(RoleAssignmentListQueryRequest roleAssignmentListQueryRequest) {
        RoleAssignmentListQueryCommand roleAssignmentListQueryCommand = adapterConverter.roleAssignmentListQueryRequestToRoleAssignmentListQueryCommand(roleAssignmentListQueryRequest);
        List<RoleAssignment> roleAssignments = roleBasicQueryService.getRoleAssignmentListWithoutToken(roleAssignmentListQueryCommand);
        List<RoleAssignmentResponse> roleAssignmentResponses = adapterConverter.roleAssignmentToRoleAssignmentResponse(roleAssignments);
        return new ResponseData<>().success(roleAssignmentResponses);
    }
}
